﻿// (c) Copyright Microsoft Corporation.
// This source is subject to [###LICENSE_NAME###].
// Please see [###LICENSE_LINK###] for details.
// All other rights reserved.

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Controls.Primitives;

namespace EnsureWeb.Controls
{
    /// <summary>
    /// The control for timeline scale rollup.
    /// </summary>
    [TemplatePart(Name = TimelineRollupControl.ElementRollupButton, Type = typeof(Button))]
    [TemplatePart(Name = TimelineRollupControl.ElementLeftButton, Type = typeof(RepeatButton))]
    [TemplatePart(Name = TimelineRollupControl.ElementRightButton, Type = typeof(RepeatButton))]
    [TemplatePart(Name = TimelineRollupControl.ElementShowTextStoryboard, Type = typeof(Storyboard))]
    public class TimelineRollupControl : Control
    {
        #region Template Part Name
        /// <summary>
        /// The UI element of RollupButton.
        /// </summary>
        private const string ElementRollupButton = "RollupButton";

        /// <summary>
        /// The UI element of LeftButton.
        /// </summary>
        private const string ElementLeftButton = "LeftButton";

        /// <summary>
        /// The UI element of RightButton.
        /// </summary>
        private const string ElementRightButton = "RightButton";

        /// <summary>
        /// The UI element of ShowTextStoryboard.
        /// </summary>
        private const string ElementShowTextStoryboard = "ShowTextStoryboard";
        #endregion

        #region Template Part Element

        /// <summary>
        /// The rollup button.
        /// </summary>
        private Button RollupButton;

        /// <summary>
        /// The button for user navigate to previous time range .
        /// </summary>
        private RepeatButton LeftButton;

        /// <summary>
        /// The button for user navigate to next time range .
        /// </summary>
        private RepeatButton RightButton;

        /// <summary>
        /// The storyboard for showing text animation.
        /// </summary>
        private Storyboard ShowTextStoryboard;
        #endregion

        #region Dependency Properties

        #region public bool CanRollup

        /// <summary>
        /// Gets or sets a value indicating whether can rollup.
        /// </summary>
        public bool CanRollup
        {
            get { return (bool)GetValue(CanRollupProperty); }
            set { SetValue(CanRollupProperty, value); }
        }

        /// <summary>
        /// The canrollup dependency property.
        /// </summary>
        public static readonly DependencyProperty CanRollupProperty =
            DependencyProperty.Register("CanRollup", typeof(bool), typeof(TimelineRollupControl), new PropertyMetadata(true, OnCanRollupChanged));

        /// <summary>
        /// Handle CanRollUp value changed.
        /// </summary>
        /// <param name="d">Event source.</param>
        /// <param name="e">Event args.</param>
        private static void OnCanRollupChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TimelineRollupControl control = d as TimelineRollupControl;
            bool value = (bool)e.NewValue;

            if (control != null)
            {
                control.OnCanRollupChanged(value);
            }
        }

        /// <summary>
        /// Handle can rollup property changed.
        /// </summary>
        /// <param name="value">New value.</param>
        private void OnCanRollupChanged(bool value)
        {
            if (this.RollupButton != null)
            {
                this.RollupButton.IsEnabled = value;
            }
        }
        #endregion

        #region public bool CanShowPrevious
        /// <summary>
        /// Gets or sets a value indicating whether can show previous of item.
        /// </summary>
        public bool CanShowPrevious
        {
            get { return (bool)GetValue(CanShowPreviousProperty); }
            set { SetValue(CanShowPreviousProperty, value); }
        }

        /// <summary>
        /// Using a DependencyProperty as the backing store for CanShowPrevious.  This enables animation, styling, binding, etc...
        /// </summary> 
        public static readonly DependencyProperty CanShowPreviousProperty =
            DependencyProperty.Register("CanShowPrevious", typeof(bool), typeof(TimelineRollupControl), new PropertyMetadata(OnCanShowPreviousChanged));

        /// <summary>
        /// Handle canshow previous property changed.
        /// </summary>
        /// <param name="d">Event source.</param>
        /// <param name="e">Event args.</param>
        private static void OnCanShowPreviousChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TimelineRollupControl control = d as TimelineRollupControl;
            bool value = (bool)e.NewValue;
            if (control != null)
            {
                control.OnCanShowPreviousChanged(value);
            }
        }

        /// <summary>
        /// Handle canshow previous property changed.
        /// </summary>
        /// <param name="value">New value.</param>
        private void OnCanShowPreviousChanged(bool value)
        {
            if (this.LeftButton != null)
            {
                this.LeftButton.IsEnabled = value;
            }
        }
        #endregion

        #region public bool CanShowNext

        /// <summary>
        /// Gets or sets a value indicating whether can show next.
        /// </summary>
        public bool CanShowNext
        {
            get { return (bool)GetValue(CanShowNextProperty); }
            set { SetValue(CanShowNextProperty, value); }
        }

        /// <summary>
        /// The can show next dependency property.
        /// </summary>
        public static readonly DependencyProperty CanShowNextProperty =
            DependencyProperty.Register("CanShowNext", typeof(bool), typeof(TimelineRollupControl), new PropertyMetadata(OnCanShowNextChanged));

        /// <summary>
        /// Handle property changed.
        /// </summary>
        /// <param name="d">Event source.</param>
        /// <param name="e">Event args.</param>
        private static void OnCanShowNextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TimelineRollupControl control = d as TimelineRollupControl;
            bool value = (bool)e.NewValue;

            if (control != null)
            {
                control.OnCanShowNextChanged(value);
            }
        }

        /// <summary>
        /// Handle canshownext property changed.
        /// </summary>
        /// <param name="value">New value.</param>
        private void OnCanShowNextChanged(bool value)
        {
            if (this.RightButton != null)
            {
                this.RightButton.IsEnabled = value;
            }
        }
        #endregion

        #region public DateTime RollupDate

        /// <summary>
        /// Gets or sets the rollup date dependency property.
        /// </summary>
        public DateTime RollupDate
        {
            get { return (DateTime)GetValue(RollupDateProperty); }
            set { SetValue(RollupDateProperty, value); }
        }

        /// <summary>
        /// Rollup date dependency property.
        /// </summary>
        public static readonly DependencyProperty RollupDateProperty =
            DependencyProperty.Register("RollupDate", typeof(DateTime), typeof(TimelineRollupControl), null);

        #endregion

        #region public string Text

        /// <summary>
        /// Gets or sets the Text value.
        /// </summary>
        public string Text
        {
            get { return (string)GetValue(TextProperty); }
            set { SetValue(TextProperty, value); }
        }

        /// <summary>
        /// The text dependency property.
        /// </summary>
        public static readonly DependencyProperty TextProperty =
            DependencyProperty.Register("Text", typeof(string), typeof(TimelineRollupControl), new PropertyMetadata(string.Empty, OnTextChanged));

        /// <summary>
        /// Execute when the text changed.
        /// </summary>
        /// <param name="d">Event source.</param>
        /// <param name="e">Event args.</param>
        private static void OnTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TimelineRollupControl control = d as TimelineRollupControl;
            string value = (string)e.NewValue;

            if (control != null)
            {
                control.OnTextChanged(value);
            }
        }

        /// <summary>
        /// Handle text changed.
        /// </summary>
        /// <param name="value">New text value.</param>
        private void OnTextChanged(string value)
        {
            if (this.RollupButton != null)
            {
                this.RollupButton.Content = value;
                this.ShowTextStoryboard.Begin();
            }
        }
        #endregion

        #endregion

        /// <summary>
        /// Click previous event handler.
        /// </summary>
        public event EventHandler ClickPrevious;

        /// <summary>
        /// Click next event handler.
        /// </summary>
        public event EventHandler ClickNext;

        /// <summary>
        /// Click text event handler.
        /// </summary>
        public event EventHandler ClickText;

        /// <summary>
        /// Initializes a new instance of the TimelineRollupControl class.
        /// </summary>
        public TimelineRollupControl()
        {
            DefaultStyleKey = typeof(TimelineRollupControl);
        }

        /// <summary>
        /// Update the scale of time line view.
        /// </summary>
        /// <param name="view">New timeline view scale.</param>
        public void UpdateTimelineView(TimeView view)
        {
            this.RollupDate = view.ParentBeginDate;
            this.Text = view.RollupText;
            this.CanRollup = view.CanRollup;
            this.CanShowNext = view.CanShowNext;
            this.CanShowPrevious = view.CanShowPrevious;
        }

        /// <summary>
        /// Invoked whenever application code or an internal process, such as a
        /// rebuilding layout pass, calls the ApplyTemplate method.
        /// </summary>
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            this.RollupButton = GetTemplateChild(TimelineRollupControl.ElementRollupButton) as Button;
            this.LeftButton = GetTemplateChild(TimelineRollupControl.ElementLeftButton) as RepeatButton;
            this.RightButton = GetTemplateChild(TimelineRollupControl.ElementRightButton) as RepeatButton;
            this.ShowTextStoryboard = GetTemplateChild(TimelineRollupControl.ElementShowTextStoryboard) as Storyboard;

            if (this.RollupButton != null)
            {
                this.RollupButton.Click += RollupButton_Click;
            }

            if (LeftButton != null)
            {
                this.LeftButton.Click += LeftButton_Click;
            }

            if (RightButton != null)
            {
                this.RightButton.Click += RightButton_Click;
            }

            UpdateVisual();
        }

        /// <summary>
        /// Handle rollup button clicked.
        /// </summary>
        /// <param name="sender">Event source.</param>
        /// <param name="e">Event args.</param>
        private void RollupButton_Click(object sender, RoutedEventArgs e)
        {
            EventHandler handler = ClickText;
            if (handler != null)
            {
                handler(this, EventArgs.Empty);
            }
        }

        /// <summary>
        /// Handle left button clicked.
        /// </summary>
        /// <param name="sender">Event source.</param>
        /// <param name="e">Event args.</param>
        private void LeftButton_Click(object sender, RoutedEventArgs e)
        {
            EventHandler handler = ClickPrevious;
            if (handler != null)
            {
                handler(this, EventArgs.Empty);
            }
        }

        /// <summary>
        /// Handle right button clicked.
        /// </summary>
        /// <param name="sender">Event source.</param>
        /// <param name="e">Event args.</param>
        private void RightButton_Click(object sender, RoutedEventArgs e)
        {
            EventHandler handler = ClickNext;
            if (handler != null)
            {
                handler(this, EventArgs.Empty);
            }
        }

        /// <summary>
        /// Update UI.
        /// </summary>
        private void UpdateVisual()
        {
            OnCanShowNextChanged(this.CanShowNext);
            OnCanShowPreviousChanged(this.CanShowPrevious);
            OnCanRollupChanged(this.CanRollup);
            OnTextChanged(this.Text);
        }
    }
}
